package com.alennus.blog.rabbitMq.spring_rabbit.config;

import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * Created by pactera on 2018/9/25.
 * 队列配置
 */
@Configuration
public class RabbitConfig {

    public static final String QUEUE_SIMPLE_HELLO_NAME = "HELLO-QUEUE-2018-9-25";
    public static final String QUEUE_SIMPLE_USER_NAME = "USER";
    public static final String QUEUE_TOPIC_MESSAGE_NAME = "TOPIC.MESSAGE";
    public static final String QUEUE_TOPIC_MESSAGES_NAME = "TOPIC.MESSAGES";
    public static final String QUEUE_FANOUT_MESSAGE_A_NAME = "FANOUT.MESSAGE.A";
    public static final String QUEUE_FANOUT_MESSAGE_B_NAME = "FANOUT.MESSAGE.B";
    public static final String QUEUE_FANOUT_MESSAGE_C_NAME = "FANOUT.MESSAGE.C";
    public static final String EXCHANGE_TOPIC_NAME = "TOPIC_EXCHANGE";
    public static final String EXCHANGE_FANOUT__NAME = "FANOUT_EXCHANGE";

    @Bean
    public Queue taskQueue(){
        return new Queue(RabbitConfig.QUEUE_SIMPLE_HELLO_NAME);
    }


    @Bean
    public Queue userQueue(){
        return  new Queue(RabbitConfig.QUEUE_SIMPLE_USER_NAME);
    }

    //===============以下是验证topic Exchange的队列==========

    @Bean
    public Queue queueTopicMessage(){
        return  new Queue(RabbitConfig.QUEUE_TOPIC_MESSAGE_NAME);
    }

    @Bean
    public Queue queueTopicMessages(){
        return  new Queue(RabbitConfig.QUEUE_TOPIC_MESSAGES_NAME);
    }
    //===============以上是验证topic Exchange的队列==========


    //===============以下是验证Fanout Exchange的队列==========

    @Bean
    public Queue queueFanoutMessageA(){
        return new Queue(RabbitConfig.QUEUE_FANOUT_MESSAGE_A_NAME);
    }

    @Bean
    public Queue queueFanoutMessageB(){
        return new Queue(RabbitConfig.QUEUE_FANOUT_MESSAGE_B_NAME);
    }

    @Bean
    public Queue queueFanoutMessageC(){
        return new Queue(RabbitConfig.QUEUE_FANOUT_MESSAGE_C_NAME);
    }
    //===============以上是验证Fanout Exchange的队列==========




    //===============定义交换机==========

    @Bean
    public TopicExchange topicExchange(){
        return new TopicExchange(RabbitConfig.EXCHANGE_TOPIC_NAME);
    }
    @Bean
    public FanoutExchange fanoutExchange(){
        return  new FanoutExchange(RabbitConfig.EXCHANGE_FANOUT__NAME);
    }


    /**
     * 将队列topic.message与exchange绑定，binding_key为topic.#,模糊匹配
     * @param queueTopicMessage  队列topic.messages
     * @param topicExchange  topicExchange
     * @return
     */
    @Bean
    Binding bindingTopicExchangeMessage(Queue queueTopicMessage, TopicExchange topicExchange) {
        return BindingBuilder.bind(queueTopicMessage).to(topicExchange).with(RabbitConfig.QUEUE_TOPIC_MESSAGE_NAME);
    }

    /**
     * 将队列topic.messages与exchange绑定，binding_key为topic.#,模糊匹配
     * @param queueTopicMessages
     * @param topicExchange
     * @return
     */
    @Bean
    Binding bindingTopicExchangeMessages(Queue queueTopicMessages, TopicExchange topicExchange) {
        return BindingBuilder.bind(queueTopicMessages).to(topicExchange).with("TOPIC.#");
    }


    /**
     * 将队列queueFanoutMessageA与fanoutExchange绑定
     * @param queueFanoutMessageA
     * @param fanoutExchange
     * @return
     */
    @Bean
    Binding bindingFanoutExchangeQueueFanoutMessageA(Queue queueFanoutMessageA,FanoutExchange fanoutExchange){
        return BindingBuilder.bind(queueFanoutMessageA).to(fanoutExchange);
    }
    /**
     * 将队列queueFanoutMessageB与fanoutExchange绑定
     * @param queueFanoutMessageB
     * @param fanoutExchange
     * @return
     */
    @Bean
    Binding bindingFanoutExchangeQueueFanoutMessageB(Queue queueFanoutMessageB,FanoutExchange fanoutExchange){
        return BindingBuilder.bind(queueFanoutMessageB).to(fanoutExchange);
    }
    /**
     * 将队列queueFanoutMessageC与fanoutExchange绑定
     *
     * Fanout 就是我们熟悉的广播模式或者订阅模式，给Fanout转发器发送消息，
     * 绑定了这个转发器的所有队列都收到这个消息。
     *
     * 这里使用三个队列来测试（也就是在Application类中创建和绑定的fanout.A、fanout.B、fanout.C）
     * 这三个队列都和Application中创建的fanoutExchange转发器绑定。
     *
     * 绑定关系可以在配置文件中配置也可以在rabbit服务器后台进行手动配置
     * 生产环境一般是在rabbit服务器后台配置，因为配置文件需要重启服务器，生产环境不允许经常重启服务
     *
     * 订阅模式即使你配置访问路由也不会生效
     *
     * @param queueFanoutMessageC
     * @param fanoutExchange
     * @return
     */
    @Bean
    Binding bindingFanoutExchangeQueueFanoutMessageC(Queue queueFanoutMessageC,FanoutExchange fanoutExchange){
        return BindingBuilder.bind(queueFanoutMessageC).to(fanoutExchange);
    }


}
